From 52c8195eb2655707cbe3dfbde3dbe0a69f8bb442 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 6 Aug 2005 09:49:22 +0000 Subject: [PATCH] This patch changes the probe notifier, per Rusty's suggestion. It also converts the balloon driver to use the notifier structure, and removes the root-watch workaround. Signed-off-by: Dan Smith --- linux-2.6-xen-sparse/arch/xen/kernel/reboot.c | 13 ++- .../drivers/xen/balloon/balloon.c | 83 +++++-------------- .../drivers/xen/xenbus/xenbus_probe.c | 29 ++++--- .../include/asm-xen/balloon.h | 3 - 4 files changed, 44 insertions(+), 84 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index 7a19712c47..ad9550748c 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -314,6 +314,9 @@ static struct xenbus_watch sysrq_watch = { static struct notifier_block xenstore_notifier; +/* Setup our watcher + NB: Assumes xenbus_lock is held! +*/ static int setup_shutdown_watcher(struct notifier_block *notifier, unsigned long event, void *data) @@ -323,12 +326,12 @@ static int setup_shutdown_watcher(struct notifier_block *notifier, int err2 = 0; #endif - down(&xenbus_lock); + BUG_ON(down_trylock(&xenbus_lock) == 0); + err1 = register_xenbus_watch(&shutdown_watch); #ifdef CONFIG_MAGIC_SYSRQ err2 = register_xenbus_watch(&sysrq_watch); #endif - up(&xenbus_lock); if (err1) { printk(KERN_ERR "Failed to set shutdown watcher\n"); @@ -348,11 +351,7 @@ static int __init setup_shutdown_event(void) xenstore_notifier.notifier_call = setup_shutdown_watcher; - if (xen_start_info.store_evtchn) { - setup_shutdown_watcher(&xenstore_notifier, 0, NULL); - } else { - register_xenstore_notifier(&xenstore_notifier); - } + register_xenstore_notifier(&xenstore_notifier); return 0; } diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index ba1e38a770..2971bc5087 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -81,9 +81,6 @@ static void balloon_process(void *unused); static DECLARE_WORK(balloon_worker, balloon_process, NULL); static struct timer_list balloon_timer; -/* Flag for dom0 xenstore workaround */ -static int balloon_xenbus_init=0; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* Use the private and mapping fields of struct page as a list. */ #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) @@ -304,15 +301,9 @@ static void set_new_target(unsigned long target) schedule_work(&balloon_worker); } -static struct xenbus_watch xb_watch = +static struct xenbus_watch target_watch = { - .node = "memory" -}; - -/* FIXME: This is part of a dom0 sequencing workaround */ -static struct xenbus_watch root_watch = -{ - .node = "/" + .node = "memory/target" }; /* React to a change in the target key */ @@ -321,29 +312,11 @@ static void watch_target(struct xenbus_watch *watch, const char *node) unsigned long new_target; int err; - if(watch == &root_watch) - { - /* FIXME: This is part of a dom0 sequencing workaround */ - if(register_xenbus_watch(&xb_watch) == 0) - { - /* - We successfully set a watch on memory/target: - now we can stop watching root - */ - unregister_xenbus_watch(&root_watch); - balloon_xenbus_init=1; - } - else - { - return; - } - } - err = xenbus_scanf("memory", "target", "%lu", &new_target); if(err != 1) { - IPRINTK("Unable to read memory/target\n"); + printk(KERN_ERR "Unable to read memory/target\n"); return; } @@ -351,41 +324,27 @@ static void watch_target(struct xenbus_watch *watch, const char *node) } -/* Init Function - Try to set up our watcher, if not already set. */ -void balloon_init_watcher(void) +/* Setup our watcher + NB: Assumes xenbus_lock is held! +*/ +int balloon_init_watcher(struct notifier_block *notifier, + unsigned long event, + void *data) { int err; - if (!xen_start_info.store_evtchn) { - IPRINTK("Delaying watcher init until xenstore is available\n"); - return; - } + BUG_ON(down_trylock(&xenbus_lock) == 0); - down(&xenbus_lock); - - if (!balloon_xenbus_init) { - err = register_xenbus_watch(&xb_watch); - if (err) { - /* BIG FAT FIXME: dom0 sequencing workaround - * dom0 can't set a watch on memory/target until - * after the tools create it. So, we have to watch - * the whole store until that happens. - * - * This will go away when we have the ability to watch - * non-existant keys - */ - register_xenbus_watch(&root_watch); - } else { - IPRINTK("Balloon xenbus watcher initialized\n"); - balloon_xenbus_init = 1; - } + err = register_xenbus_watch(&target_watch); + + if (err) { + printk(KERN_ERR "Failed to set balloon watcher\n"); } - up(&xenbus_lock); + return NOTIFY_DONE; + } -EXPORT_SYMBOL(balloon_init_watcher); - static int balloon_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { @@ -439,6 +398,8 @@ static int balloon_read(char *page, char **start, off_t off, return len; } +static struct notifier_block xenstore_notifier; + static int __init balloon_init(void) { unsigned long pfn; @@ -474,11 +435,11 @@ static int __init balloon_init(void) balloon_append(page); } - xb_watch.callback = watch_target; - root_watch.callback = watch_target; - - balloon_init_watcher(); + target_watch.callback = watch_target; + xenstore_notifier.notifier_call = balloon_init_watcher; + register_xenstore_notifier(&xenstore_notifier); + return 0; } diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 706d351121..e5c625d752 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -41,9 +41,6 @@ #define streq(a, b) (strcmp((a), (b)) == 0) -/* Protects notifier chain */ -DECLARE_MUTEX(xenstore_control); - static struct notifier_block *xenstore_chain; /* If something in array of ids matches this device, return it. */ @@ -317,21 +314,27 @@ void xenbus_resume(void) int register_xenstore_notifier(struct notifier_block *nb) { - int ret; + int ret = 0; + + down(&xenbus_lock); + + if (xen_start_info.store_evtchn) { + ret = nb->notifier_call(nb, 0, NULL); + } else { + notifier_chain_register(&xenstore_chain, nb); + } + + up(&xenbus_lock); - if ((ret = down_interruptible(&xenstore_control)) != 0) - return ret; - ret = notifier_chain_register(&xenstore_chain, nb); - up(&xenstore_control); return ret; } EXPORT_SYMBOL(register_xenstore_notifier); void unregister_xenstore_notifier(struct notifier_block *nb) { - down(&xenstore_control); + down(&xenbus_lock); notifier_chain_unregister(&xenstore_chain, nb); - up(&xenstore_control); + up(&xenbus_lock); } EXPORT_SYMBOL(unregister_xenstore_notifier); @@ -349,7 +352,10 @@ int do_xenbus_probe(void *unused) return err; } + down(&xenbus_lock); err = notifier_call_chain(&xenstore_chain, 0, 0); + up(&xenbus_lock); + if (err == NOTIFY_BAD) { printk("%s: calling xenstore notify chain failed\n", __FUNCTION__); @@ -358,9 +364,6 @@ int do_xenbus_probe(void *unused) err = 0; - /* Initialize non-xenbus drivers */ - balloon_init_watcher(); - down(&xenbus_lock); /* Enumerate devices in xenstore. */ xenbus_probe_devices("device"); diff --git a/linux-2.6-xen-sparse/include/asm-xen/balloon.h b/linux-2.6-xen-sparse/include/asm-xen/balloon.h index 413919b322..80ef4acefc 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/balloon.h +++ b/linux-2.6-xen-sparse/include/asm-xen/balloon.h @@ -48,7 +48,4 @@ extern spinlock_t balloon_lock; #define balloon_lock(__flags) spin_lock_irqsave(&balloon_lock, __flags) #define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags) -/* Init Function - Try to set up our watcher, if not already set. */ -void balloon_init_watcher(void); - #endif /* __ASM_BALLOON_H__ */ -- 2.30.2